package com.LachesismStorm.lachesism.downloader;

import com.LachesismStorm.lachesism.core.util.LachesismTools;
import com.aayushatharva.brotli4j.Brotli4jLoader;
import com.aayushatharva.brotli4j.decoder.BrotliInputStream;
import org.json.JSONArray;
import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;

public class VideoLinkDownloader {

    private static final String INPUT_HTML_PATH = "/Users/yuno/java/code/LachesismStorm/LachesismStorm/lachesism-service/src/main/resources/html/temp.html";
    private static final String OUTPUT_FILE_PATH = "/Users/yuno/Downloads/x/link2.txt";
    private static final String OUTPUT_FILE_PATH_2 = "/Users/yuno/Downloads/x/link2.txt";
    private static final String API_URL = "https://download-x-video.com/api/parse";
    public static Map<String, String> parseHtmlContent() throws IOException {
        // 创建结果Map存储link和desc
        Map<String, String> resultMap = new HashMap<>();

        // 使用Jsoup解析HTML
        Document doc = Jsoup.parse(new File(INPUT_HTML_PATH), "UTF-8");

        // 选择所有符合模式的大div元素
        Elements bigDivs = doc.select("#react-root > div > div > div.css-175oi2r.r-1f2l425.r-13qz1uu.r-417010.r-18u37iz > " +
                "main > div > div > div > div.css-175oi2r.r-14lw9ot.r-jxzhtn.r-1ua6aaf.r-th6na.r-1phboty.r-16y2uox.r-184en5c.r-1abdc3e.r-1lg4w6u.r-f8sm7e.r-13qz1uu.r-1ye8kvj > " +
                "div > div:nth-child(3) > div > div > section > div > div > div:nth-child(n)");

        // 遍历每个大div
        for (Element bigDiv : bigDivs) {
            try {
                // 提取link
                Element linkElement = bigDiv.selectFirst("div[id^=id__] > div.css-175oi2r.r-18u37iz.r-1wbh5a2.r-1ez5h0i > " +
                        "div > div.css-175oi2r.r-18u37iz.r-1q142lx > a");
                String href = linkElement != null ? linkElement.attr("href") : "";
                String link = "https://x.com" + href;

                // 提取desc - 获取特定id下的span(1)和span(3)
                String desc = "";
                Elements idElements = bigDiv.select("div[id^=id__]");
                if (!idElements.isEmpty()) {
                    // 取第一个匹配的id元素
                    Element descContainer = idElements.first();
                    Element span1 = descContainer.selectFirst("span:nth-child(1)");
                    Element span3 = descContainer.selectFirst("span:nth-child(3)");

                    String text1 = span1 != null ? span1.text() : "";
                    String text3 = span3 != null ? span3.text() : "";
                    desc = text1 + text3;
                }

                // 将结果放入map
                if (!link.isEmpty() && !desc.isEmpty()) {
                    resultMap.put(link, desc);
                }

            } catch (Exception e) {
                System.err.println("Error processing div: " + e.getMessage());
                continue;
            }
        }

        return resultMap;
    }



    public static void main(String[] args) {
        // Step 1: Extract video links from HTML file
        extractVideoLinksFromHtml(INPUT_HTML_PATH, OUTPUT_FILE_PATH);

        // Step 2: Deduplicate and store unique links
        deduplicateLinks(OUTPUT_FILE_PATH);

        // Step 3: Process each video link and fetch video information
        processVideoLinksFromFile(OUTPUT_FILE_PATH);
    }

    // Method to ensure the file and its parent directories exist
    private static void ensureFileExists(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            file.getParentFile().mkdirs(); // Ensure parent directories exist
            try {
                file.createNewFile(); // Create the file
            } catch (IOException e) {
                System.err.println("Error creating file: " + filePath);
                e.printStackTrace();
            }
        }
    }

    // Extract video links from the HTML file and write to the output file
    private static void extractVideoLinksFromHtml(String inputHtmlPath, String outputFilePath) {
        try {
            // Load HTML document
            Document doc = Jsoup.parse(new File(inputHtmlPath), "UTF-8");

            // Select all video links
            Elements links = doc.select("[id^=verticalGridItem-][id$=-profile-grid-0] > div > div > div > a");

            // Ensure output file exists
            ensureFileExists(outputFilePath);

            // Write the links to the output file
            try (FileWriter writer = new FileWriter(outputFilePath, true)) {
                for (Element link : links) {
                    String href = link.attr("href");
                    href = "https://x.com" + href;
                    if (!href.contains("/photo")) {
                        href = href.replaceAll("/video/1", "");
                        writer.write(href + System.lineSeparator());
                        System.out.println("Extracted link: " + href);
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("Error extracting video links from HTML.");
            e.printStackTrace();
        }
    }

    // Deduplicate video links and write unique links back to the file
    private static void deduplicateLinks(String filePath) {
        Set<String> existingLinks = new HashSet<>();
        try {
            Files.lines(Paths.get(filePath)).forEach(existingLinks::add);
            // Ensure output file exists
            ensureFileExists(filePath);

            // Write deduplicated links to the file
            try (FileWriter writer = new FileWriter(filePath)) {
                for (String uniqueLink : existingLinks) {
                    writer.write(uniqueLink + System.lineSeparator());
                    System.out.println("Deduplicated link: " + uniqueLink);
                }
            }
        } catch (IOException e) {
            System.err.println("Error reading or writing to the file: " + filePath);
            e.printStackTrace();
        }
    }

    // Process each video link from the file and fetch video information
    private static void processVideoLinksFromFile(String filePath) {
        Brotli4jLoader.ensureAvailability(); // Ensure Brotli decoder is available
        List<String> links = new ArrayList<String>();
        try (BufferedReader br = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                String videoUrl = line.trim(); // Trim whitespace
                try {
                    String response = fetchVideoInfo(videoUrl);
                    if (response != null) {
                        String link = parseVideoUrl(response);
                        links.add(link);
                    }
                } catch (Exception e) {
                    System.err.println("Error processing URL: " + videoUrl);
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            System.err.println("Error reading from file: " + filePath);
            e.printStackTrace();
        }
        batchGetDownloadLink(links);
    }

    // Fetch video information by sending a POST request
    private static String fetchVideoInfo(String videoUrl) throws IOException {
        String jsonData = String.format("{\"url\":\"%s\"}", videoUrl);

        HttpURLConnection con = (HttpURLConnection) new URL(API_URL).openConnection();
        con.setRequestMethod("POST");
        con.setRequestProperty("Content-Type", "application/json");
        con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
        con.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
        con.setDoOutput(true);

        // Send the request
        try (OutputStream os = con.getOutputStream()) {
            os.write(jsonData.getBytes(StandardCharsets.UTF_8));
        }

        // Handle response with possible Brotli compression
        InputStream inputStream = "br".equalsIgnoreCase(con.getContentEncoding())
                ? new BrotliInputStream(con.getInputStream())
                : con.getInputStream();

        // Read the response
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            return response.toString();
        }
    }

    // Parse the video information and extract the video URL
    private static String parseVideoUrl(String jsonResponse) {

        JSONObject jsonObject = new JSONObject(jsonResponse);
        String desc = (String) jsonObject.get("title");
        JSONArray videoInfos = jsonObject.getJSONArray("videoInfos");
        // Get the last video info
        JSONObject videoData = videoInfos.getJSONObject(videoInfos.length() - 1);
        System.out.println("Video URL: " + videoData.optString("url"));
        return videoData.optString("url");
    }

    private static void batchGetDownloadLink(List<String> links) {
        ensureFileExists(OUTPUT_FILE_PATH_2);
        // Write the URL to the output file
        for (String link : links) {
            try (FileWriter writer = new FileWriter(OUTPUT_FILE_PATH_2, true)) {
                writer.write(link + System.lineSeparator());
            } catch (IOException e) {
                System.err.println("Error writing to file: " + OUTPUT_FILE_PATH_2);
                e.printStackTrace();
            }
        }
    }

}
